<?php

namespace App\Http\Service;

use App\Http\Repository\ActivityRepository;
use App\Http\Criteria\PaginateCriteria;
use App\Http\Criteria\OrderBySortOrderCriteria;
use App\Http\Criteria\OrderByCreatedAtCriteria;
use App\Http\Criteria\IsActiveCriteria;
use App\Http\Criteria\IDCriteria;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Contracts\Encryption\DecryptException;


class ActivityService extends BaseService
{
    protected $rep;

    public function __construct(ActivityRepository $repository)
    {
        $this->rep = $repository;

    }

    public function list($user, $page = 1)
    {
        $this->rep->pushCriteria(new OrderBySortOrderCriteria());
        $this->rep->pushCriteria(new OrderByCreatedAtCriteria());
        $this->rep->pushCriteria(new IsActiveCriteria());
        $this->rep->pushCriteria(new PaginateCriteria($page));

        return $this->rep->with('goods')->with(['log' => function ($query) use ($user) {
            $query->where('user_id', $user->id);
        }])->with(['share_log' => function ($query) use ($user) {
            $query->where('user_id', $user->id);
        }])->get();
    }

    public function getDetail($user, $id)
    {

        $this->rep->pushCriteria(new IDCriteria($id));

        return $this->rep->with(['goods' => function ($query) {
            $query->with(['images' => function($query) {
                $query->orderBy('sort_order', 'desc')->orderBy('created_at', 'desc');
            }]);
        }])->with(['log' => function ($query) use ($user) {
            $query->where('user_id', $user->id);
        }])->first();

    }


    public function getRobToken($user, $activityId)
    {
        $redis = getRedis($user->id);

        $robTokenFlagKey = $this->getRobTokenFlagKey($user->id, $activityId);
        $robTokenKey = $this->getRobTokenKey($user->id, $activityId);

        list($flag, $robToken) = $redis->mGet([$robTokenFlagKey, $robTokenKey]);

        if ($flag != null && $robToken != null) {
            return $robToken;
        }

        // 限制同一个账号并发发出多个请求
        $redis->watch($robTokenFlagKey);
        $redis->multi();
        $redis->incr($robTokenFlagKey);
        if(!$redis->exec()) {
            return $redis->get($robTokenKey);
        }

        $robTokenInfo = [
            'user_id'     => $user->id,
            'activity_id' => $activityId,
            'timestamp'   => time(),
        ];

        $robToken = Crypt::encrypt($robTokenInfo);

        $redis->set($robTokenKey, $robToken);
        return $robToken;
    }

    public function decryptRobToken($robToken) {
        try {
            return Crypt::decrypt($robToken);
        } catch (DecryptException $e) {
            return false;
        }
    }

    private function getRobTokenFlagKey($userId, $activityId) {
        return 'user_id:' . $userId . ':activity_id:' . $activityId . ':rob_token_flag';
    }

    private function getRobTokenKey($userId, $activityId) {
        return 'user_id:' . $userId . ':activity_id:' . $activityId . ':rob_token';
    }
}
